const IsEqual = require('../template')

console.log("=== IsEqual 高级方法测试 ===")

// 测试自定义比较函数
console.log(
  "自定义比较函数:", (() => {
    const obj1 = { a: 1, b: 'test' }
    const obj2 = { a: 1, b: 'TEST' }

    return IsEqual.isEqualWithCustomizer(obj1, obj2, (value1, value2, key) => {
      if (key === 'b') return value1.toLowerCase() === value2.toLowerCase()
      return undefined // 使用默认比较
    }) === true
  })()
)

// 测试循环引用比较
console.log(
  "循环引用比较:", (() => {
    const obj1 = { a: 1 }
    obj1.self = obj1

    const obj2 = { a: 1 }
    obj2.self = obj2

    try {
      return IsEqual.isEqualWithCircular(obj1, obj2) === true
    } catch (error) {
      return true // 循环引用应该正确处理
    }
  })()
)

// 测试类型检查比较
console.log(
  "类型检查比较:", (() => {
    return IsEqual.isEqualWithTypeCheck(42, '42', false) === true && // 不严格类型检查
      IsEqual.isEqualWithTypeCheck(42, '42', true) === false && // 严格类型检查
      IsEqual.isEqualWithTypeCheck(1, 1, true) === true &&
      IsEqual.isEqualWithTypeCheck('test', 'test', true) === true
  })()
)

// 测试深度限制比较
console.log(
  "深度限制比较:", (() => {
    const obj1 = { a: { b: { c: { d: 'deep' } } } }
    const obj2 = { a: { b: { c: { d: 'deep' } } } }

    return IsEqual.isEqualWithDepth(obj1, obj2, 3) === true &&
      IsEqual.isEqualWithDepth(obj1, obj2, 2) === false
  })()
)

// 测试属性过滤比较
console.log(
  "属性过滤比较:", (() => {
    const obj1 = { a: 1, b: 2, c: 3, d: 4 }
    const obj2 = { a: 1, b: 2, c: 5, d: 4 }

    return IsEqual.isEqualWithFilter(obj1, obj2, (value, key) => {
      return key !== 'c' // 忽略c属性
    }) === true
  })()
)

// 测试属性映射比较
console.log(
  "属性映射比较:", (() => {
    const obj1 = { a: 1, b: 2 }
    const obj2 = { new_a: 1, new_b: 2 }

    return IsEqual.isEqualWithMapper(obj1, obj2, (value, key) => {
      return { [`new_${key}`]: value }
    }) === true
  })()
)

// 测试验证比较
console.log(
  "验证比较:", (() => {
    const obj1 = { name: 'John', age: 30 }
    const obj2 = { name: 'John', age: 30 }
    const schema = {
      name: { type: 'string', required: true },
      age: { type: 'number', min: 0, max: 150 }
    }

    try {
      return IsEqual.isEqualWithValidation(obj1, obj2, schema) === true
    } catch (error) {
      return false
    }
  })()
)

// 测试异步比较
console.log(
  "异步比较:", (() => {
    const obj1 = { a: 1, b: 'test' }
    const obj2 = { a: 1, b: 'TEST' }

    return IsEqual.isEqualAsync(obj1, obj2, async (value1, value2, key) => {
      await new Promise(resolve => setTimeout(resolve, 1))
      if (key === 'b') return value1.toLowerCase() === value2.toLowerCase()
      return undefined
    }).then(result => {
      return result === true
    }).catch(() => false)
  })()
)

// 测试并发比较
console.log(
  "并发比较:", (() => {
    const obj1 = { a: 1, b: 2, c: 3, d: 4, e: 5 }
    const obj2 = { a: 1, b: 2, c: 3, d: 4, e: 5 }

    return IsEqual.isEqualConcurrent(obj1, obj2, async (value1, value2, key) => {
      await new Promise(resolve => setTimeout(resolve, 1))
      return value1 === value2
    }, 3).then(result => {
      return result === true
    }).catch(() => false)
  })()
)

// 测试统计比较
console.log(
  "统计比较:", (() => {
    const obj1 = { a: 1, b: { c: 2 }, d: [3, 4] }
    const obj2 = { a: 1, b: { c: 2 }, d: [3, 4] }
    const result = IsEqual.isEqualWithStats(obj1, obj2)

    return typeof result === 'object' &&
      typeof result.data === 'boolean' &&
      result.data === true &&
      typeof result.stats === 'object' &&
      result.stats.objectsCompared > 0 &&
      result.stats.arraysCompared > 0 &&
      result.stats.primitivesCompared > 0
  })()
)

// 测试复杂嵌套结构比较
console.log(
  "复杂嵌套结构比较:", (() => {
    const obj1 = {
      users: [
        { id: 1, profile: { name: 'Alice', settings: { theme: 'dark' } } },
        { id: 2, profile: { name: 'Bob', settings: { theme: 'light' } } }
      ],
      meta: { total: 2, page: 1 },
      config: { api: { baseUrl: 'https://api.example.com' } }
    }
    const obj2 = {
      users: [
        { id: 1, profile: { name: 'Alice', settings: { theme: 'dark' } } },
        { id: 2, profile: { name: 'Bob', settings: { theme: 'light' } } },
      ],
      meta: { total: 2, page: 1 },
      config: { api: { baseUrl: 'https://api.example.com' } }
    }

    return IsEqual.isEqual(obj1, obj2) === true
  })()
)

// 测试Map和Set比较
console.log(
  "Map和Set比较:", (() => {
    const map1 = new Map([['a', 1], ['b', 2]])
    const map2 = new Map([['a', 1], ['b', 2]])
    const set1 = new Set([1, 2, 3])
    const set2 = new Set([1, 2, 3])

    return IsEqual.isEqual(map1, map2) === true &&
      IsEqual.isEqual(set1, set2) === true &&
      IsEqual.isEqual(map1, set1) === false
  })()
)

// 测试TypedArray比较
console.log(
  "TypedArray比较:", (() => {
    const arr1 = new Uint8Array([1, 2, 3])
    const arr2 = new Uint8Array([1, 2, 3])
    const arr3 = new Uint8Array([1, 2, 4])

    return IsEqual.isEqual(arr1, arr2) === true &&
      IsEqual.isEqual(arr1, arr3) === false
  })()
)

// 测试ArrayBuffer比较
console.log(
  "ArrayBuffer比较:", (() => {
    const buffer1 = new ArrayBuffer(8)
    const buffer2 = new ArrayBuffer(8)
    const buffer3 = new ArrayBuffer(16)

    return IsEqual.isEqual(buffer1, buffer2) === true &&
      IsEqual.isEqual(buffer1, buffer3) === false
  })()
)

// 测试DataView比较
console.log(
  "DataView比较:", (() => {
    const buffer1 = new ArrayBuffer(8)
    const buffer2 = new ArrayBuffer(8)
    const view1 = new DataView(buffer1)
    const view2 = new DataView(buffer2)
    const view3 = new DataView(buffer1)

    view1.setUint8(0, 1)
    view2.setUint8(0, 1)
    view3.setUint8(0, 2)

    return IsEqual.isEqual(view1, view2) === true &&
      IsEqual.isEqual(view1, view3) === false
  })()
)

// 测试Error对象比较
console.log(
  "Error对象比较:", (() => {
    const error1 = new Error('test error')
    const error2 = new Error('test error')
    const error3 = new Error('different error')

    error1.code = 'ERR_001'
    error2.code = 'ERR_001'
    error3.code = 'ERR_002'

    return IsEqual.isEqual(error1, error2) === true &&
      IsEqual.isEqual(error1, error3) === false
  })()
)

// 测试Date对象比较
console.log(
  "Date对象比较:", (() => {
    const date1 = new Date('2023-01-01')
    const date2 = new Date('2023-01-01')
    const date3 = new Date('2023-01-02')

    return IsEqual.isEqual(date1, date2) === true &&
      IsEqual.isEqual(date1, date3) === false
  })()
)

// 测试RegExp对象比较
console.log(
  "RegExp对象比较:", (() => {
    const regex1 = /test/gi
    const regex2 = /test/gi
    const regex3 = /test/g
    const regex4 = /test/i

    return IsEqual.isEqual(regex1, regex2) === true &&
      IsEqual.isEqual(regex1, regex3) === false &&
      IsEqual.isEqual(regex1, regex4) === false
  })()
)

// 测试Symbol比较
console.log(
  "Symbol比较:", (() => {
    const sym1 = Symbol('test')
    const sym2 = Symbol('test')
    const sym3 = sym1

    return IsEqual.isEqual(sym1, sym2) === false && // 不同的Symbol
      IsEqual.isEqual(sym1, sym3) === true &&  // 相同的Symbol
      IsEqual.isEqual(sym1, 'test') === false
  })()
)

// 测试BigInt比较
console.log(
  "BigInt比较:", (() => {
    const big1 = BigInt(123)
    const big2 = BigInt(123)
    const big3 = BigInt(124)

    return IsEqual.isEqual(big1, big2) === true &&
      IsEqual.isEqual(big1, big3) === false &&
      IsEqual.isEqual(big1, 123) === false &&
      IsEqual.isEqual(big1, '123') === false
  })()
)

console.log("=== IsEqual 高级方法测试完成 ===")
